/**
 * Framework for batch testing user profile models
 * Final project by Sergey Nepomnyachiy and Julia Polchin
 * Supervisor: Tsvi Kuflik
 *
 */
package models.collaborative;

import java.util.Collection;
import java.util.Vector;

import core.environment.fVector;

/**
 * Facade class for collaborative filtering system implementation This is the
 * class that will be introduced to the framework
 * 
 * @author Sergey and Julia
 * 
 */
public class Facade {
	private Integer userId;
	private Vector<Double> ratings;

	/**
	 * @param id
	 */
	public Facade(Integer id) {
		this.setUserId(id);
		this.ratings = new Vector<Double>(111);
	}

	/**
	 * just in case: safely convert from Collection<Object> to Vector<Double>
	 * 
	 * @param userRatings
	 *            Collection of ratings for items in the system
	 * @return Vector of Doubles formed out of 'userRatings' elements
	 */
	public static Vector<Double> convertCollection(
			Collection<Object> userRatings) {
		Vector<Double> rates = new Vector<Double>();
		for (Object obj : userRatings)
			rates.add((Double) obj);
		return rates;
	}
	
	public static Vector<Integer> convertCollectionI(
			Collection<Object> userRatings) {
		Vector<Integer> rates = new Vector<Integer>();
		for (Object obj : userRatings)
			rates.add((Integer) obj);
		return rates;
	}

	/**
	 * just in case: safely convert from Collection<Object> to Vector<Double>
	 * 
	 * @param userRatings
	 *            userRatings Collection of ratings for items in the system
	 * @return
	 */
	public static Collection<Object> convertVector(Vector<?> userRatings) {
		Vector<Object> rates = new Vector<Object>(userRatings.size());
		for (Object d : userRatings)
			rates.add(d);
		return rates;
	}



	/**
	 * @param userRatings
	 */
	public static void addUser(Collection<Object> userRatings,
			Collection<Object> indices
			) {
		Collaborative.getInstance()
				.addNeighbour(convertCollection(userRatings), convertCollectionI(indices));
	}	
	/**
	 * @param userRatings
	 */
	public static void addUser(fVector userRatings, fVector indices) {
		
		Collaborative.getInstance().addNeighbour(convertCollection(userRatings), convertCollectionI(indices));
	}

	
	/**
	 * @param userRatings
	 */
	public static void addUser(Vector<Double> userRatings) {
		Collaborative.getInstance().addNeighbour(userRatings);
	}

	/**
	 * @param itemId 
	 * @param rating
	 */
	@SuppressWarnings("boxing")
	public void trainUser(Integer itemId, Double rating) {
		Double nll = 0.0;
		for (int i = this.ratings.size(); i <= itemId; ++i) //if the itemid is outside of vector - enlarge it
			this.ratings.add(nll);
		this.ratings.setElementAt(rating, itemId);
		
	}

	/**
	 * @param itemId
	 * @return
	 */
	@SuppressWarnings({ "boxing" })
	public Double predict(Integer itemId) {
		return Collaborative.getInstance().predictRatings(this.ratings)
				.elementAt(itemId);
	}

	/**
		 * 
		 */
	public static void clearAll() {
		Collaborative.getInstance().clearAll();
	}

	/**
	 * @param name
	 * @param cnst
	 */
	@SuppressWarnings("nls")
	public static void injectConstants(String name, Object cnst) {
		if (name.equals("k"))
			Collaborative.getInstance().setK((Integer) cnst);
	}

	/**
	 * @param cnst
	 */
	public static void injectConstants(Integer cnst) {
		Collaborative.getInstance().setK(cnst);
	}

	/**
	 * @param userId
	 *            the userId to set
	 */
	public void setUserId(Integer userId) {
		this.userId = userId;
	}

	/**
	 * @return the userId
	 */
	public Integer getUserId() {
		return this.userId;
	}

}
